package com.canaan.business.service.basic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.canaan.business.common.enums.basic.CodeRulePropertyEnum;
import com.canaan.business.common.enums.basic.RuleTypeEnum;
import com.canaan.business.domain.basic.WmsCodeRule;
import com.canaan.business.domain.basic.WmsCodeRuleDetail;
import com.canaan.business.domain.basic.WmsCodeRuleProduct;
import com.canaan.business.domain.basic.WmsProduct;
import com.canaan.business.domain.storehouse.WmsBarcodeRecord;
import com.canaan.business.mapper.basic.WmsCodeRuleProductMapper;
import com.canaan.business.service.basic.IWmsCodeRuleDetailService;
import com.canaan.business.service.basic.IWmsCodeRuleProductService;
import com.canaan.business.service.basic.IWmsCodeRuleService;
import com.canaan.business.service.basic.IWmsProductService;
import com.canaan.business.service.storehouse.IWmsBarcodeRecordService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.StringUtils;
import com.canaan.common.utils.TableNoUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 物料条码规则Service业务层处理
 *
 * @author ruoyi
 * @date 2023-01-29
 */
@Service
public class WmsCodeRuleProductServiceImpl implements IWmsCodeRuleProductService {
    @Resource
    private WmsCodeRuleProductMapper wmsCodeRuleProductMapper;
    @Resource
    private IWmsProductService wmsProductService;
    @Resource
    private IWmsCodeRuleService wmsCodeRuleService;
    @Resource
    private IWmsCodeRuleDetailService wmsCodeRuleDetailService;
    @Resource
    private IWmsBarcodeRecordService barcodeRecordService;
    /**
     * 查询物料条码规则
     *
     * @param id 物料条码规则主键
     * @return 物料条码规则
     */
    @Override
    public WmsCodeRuleProduct selectWmsCodeRuleProductById(Long id) {
        return wmsCodeRuleProductMapper.selectWmsCodeRuleProductById(id);
    }

    public WmsCodeRuleProduct selectWmsCodeRuleProductByProductNo(String productNo,String ruleType) {
        return wmsCodeRuleProductMapper.selectWmsCodeRuleProductByProductNo(productNo,ruleType);
    }
    /**
     * 查询物料条码规则列表
     *
     * @param wmsCodeRuleProduct 物料条码规则
     * @return 物料条码规则
     */
    @Override
    public List<WmsCodeRuleProduct> selectWmsCodeRuleProductList(WmsCodeRuleProduct wmsCodeRuleProduct) {
        return wmsCodeRuleProductMapper.selectWmsCodeRuleProductList(wmsCodeRuleProduct);
    }

    /**
     * 新增物料条码规则
     *
     * @param wmsCodeRuleProduct 物料条码规则
     * @return 结果
     */
    @Override
    public int insertWmsCodeRuleProduct(WmsCodeRuleProduct wmsCodeRuleProduct) {
        wmsCodeRuleProduct.setCreateTime(DateUtils.getNowDate());
        if(StringUtils.isBlank(wmsCodeRuleProduct.getNo())){
            wmsCodeRuleProduct.setNo(TableNoUtil.getNo(WmsCodeRuleDetail.class));
        }
        wmsCodeRuleProduct.setCreateBy(SecurityUtils.getUsername());
        return wmsCodeRuleProductMapper.insertWmsCodeRuleProduct(wmsCodeRuleProduct);
    }

    /**
     * 批量新增物料条码规则
     *
     * @param codeRuleProductList 物料条码规则列表
     * @return 结果
     */
    @Override
    public int batchInsertWmsCodeRuleProduct(List<WmsCodeRuleProduct> codeRuleProductList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (WmsCodeRuleProduct codeRuleProduct : codeRuleProductList){
            if(StringUtils.isBlank(codeRuleProduct.getNo())){
                codeRuleProduct.setNo(TableNoUtil.getNo(WmsCodeRuleProduct.class));
            }
            codeRuleProduct.setCreateBy(username);
            codeRuleProduct.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<codeRuleProductList.size();) {
            int endIndex = i+500;
            if (endIndex > codeRuleProductList.size()) {
                endIndex = codeRuleProductList.size();
            }
            insertNum = insertNum + wmsCodeRuleProductMapper.batchInsertWmsCodeRuleProduct(codeRuleProductList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }


    /**
     * 修改物料条码规则
     *
     * @param wmsCodeRuleProduct 物料条码规则
     * @return 结果
     */
    @Override
    public int updateWmsCodeRuleProduct(WmsCodeRuleProduct wmsCodeRuleProduct) {
        wmsCodeRuleProduct.setUpdateBy(SecurityUtils.getUsername());
        wmsCodeRuleProduct.setUpdateTime(DateUtils.getNowDate());
        return wmsCodeRuleProductMapper.updateWmsCodeRuleProduct(wmsCodeRuleProduct);
    }

    /**
     * 批量删除物料条码规则
     *
     * @param ids 需要删除的物料条码规则主键
     * @return 结果
     */
    @Override
    public int deleteWmsCodeRuleProductByIds(Long[] ids) {
        return wmsCodeRuleProductMapper.deleteWmsCodeRuleProductByIds(ids);
    }

    /**
     * 删除物料条码规则信息
     *
     * @param id 物料条码规则主键
     * @return 结果
     */
    @Override
    public int deleteWmsCodeRuleProductById(Long id) {
        return wmsCodeRuleProductMapper.deleteWmsCodeRuleProductById(id);
    }

    @Override
    public List<String> importExcel(List<WmsCodeRuleProduct> list) {
        List<String> errMesList = new ArrayList<>();
        for (WmsCodeRuleProduct wmsCodeRuleProduct : list) {
            wmsCodeRuleProduct.setNo(TableNoUtil.getNo(WmsCodeRuleProduct.class));
            wmsCodeRuleProduct.setCreateBy(SecurityUtils.getUsername());
            wmsCodeRuleProduct.setCreateTime(DateUtils.getNowDate());
            WmsProduct wmsProduct = wmsProductService.selectWmsProductByProductNo(wmsCodeRuleProduct.getProductNo());
            if (wmsProduct == null) {
                errMesList.add("找不到物料编码：" + wmsCodeRuleProduct.getProductNo());
                continue;
            }
            wmsCodeRuleProduct.setProductName(wmsProduct.getProductName());
            wmsCodeRuleProduct.setProductNo(wmsCodeRuleProduct.getProductNo());
            wmsCodeRuleProduct.setProductType(wmsProduct.getProductType());
            WmsCodeRule wmsCodeRule = wmsCodeRuleService.selectWmsCodeRuleByNo(wmsCodeRuleProduct.getRuleNo());
            if (wmsCodeRule == null) {
                errMesList.add("条码规则编号：" + wmsCodeRuleProduct.getRuleNo());
                continue;
            }
            wmsCodeRuleProduct.setRuleName(wmsCodeRule.getRuleName());
            wmsCodeRuleProduct.setRuleNo(wmsCodeRule.getNo());
            wmsCodeRuleProduct.setRuleType(wmsCodeRule.getRuleType());
//            wmsCodeRuleProductMapper.insertWmsCodeRuleProduct(wmsCodeRuleProduct);
        }
        if(errMesList.isEmpty()){
            wmsCodeRuleProductMapper.batchInsertWmsCodeRuleProduct(list);
        }
        return errMesList;
    }


    /**
     * 获取条码
     * @author 梁建设
     * @since 2023/2/13 下午5:52
     */
    public synchronized String  getBarcode(String productNo) {
        WmsCodeRuleProduct wmsCodeRuleProduct = this.selectWmsCodeRuleProductByProductNo(productNo, RuleTypeEnum.BARCODE.getCode());
        if (wmsCodeRuleProduct == null) {
            WmsProduct wmsProduct = wmsProductService.selectWmsProductByProductNo(productNo);
            wmsCodeRuleProduct = this.selectWmsCodeRuleProductByProductType(wmsProduct.getProductType());
        }
        if (wmsCodeRuleProduct == null)  {
            wmsCodeRuleProduct = this.selectCommonWmsCodeRuleProduct();
        }
        if (wmsCodeRuleProduct == null) {
            throw new ServiceException("请配置物料条码规则");
        }
        WmsCodeRule wmsCodeRule = wmsCodeRuleService.selectWmsCodeRuleByNo(wmsCodeRuleProduct.getRuleNo());
        if (wmsCodeRule == null) {
            throw new ServiceException("请配置物料条码规则");
        }
        List<WmsCodeRuleDetail> wmsCodeRuleDetails = wmsCodeRuleDetailService.selectWmsCodeRuleDetailListByRuleNo(wmsCodeRule.getNo());
        if (CollUtil.isEmpty(wmsCodeRuleDetails)) {
            throw new ServiceException("请配置物料条码规则明细");
        }
        wmsCodeRuleDetails = wmsCodeRuleDetails.stream().sorted(Comparator.comparing(WmsCodeRuleDetail::getSort)).collect(Collectors.toList());
        StringBuilder str = new StringBuilder();
        if (StrUtil.isNotEmpty(wmsCodeRule.getPrefix())) {
            str.append(wmsCodeRule.getPrefix());
        }
        List<String> codeList = new ArrayList<>();
        int serialNumIndex =-1;
        int serialNumLength= 0;
        for (WmsCodeRuleDetail wmsCodeRuleDetail : wmsCodeRuleDetails) {
            if (CodeRulePropertyEnum.PRODUCT_NO.getCode().equals(wmsCodeRuleDetail.getProperty())) {
                codeList.add(productNo);
                appendStr(str,"_",productNo.length());
            } else if (CodeRulePropertyEnum.SYSTEM_TIME.getCode().equals(wmsCodeRuleDetail.getProperty())) {
                if (StrUtil.isNotEmpty(wmsCodeRuleDetail.getParam())){
                    String systemTime = DateUtil.format(new Date(), wmsCodeRuleDetail.getParam());
                    codeList.add(systemTime);
                    str.append(systemTime);
                } else {
                    String systemTime = DateUtil.format(new Date(), "yyyyMMdd");
                    codeList.add(systemTime);
                    str.append(systemTime);
                }
            } else if (CodeRulePropertyEnum.SERIAL_NUM.getCode().equals(wmsCodeRuleDetail.getProperty())) {
                if (StrUtil.isNotEmpty(wmsCodeRuleDetail.getParam())){
                    serialNumIndex = codeList.size();
                    codeList.add("");
                    serialNumLength = Integer.parseInt(wmsCodeRuleDetail.getParam());
                    appendStr(str,"_",serialNumLength);
                } else {
                    serialNumIndex = codeList.size();
                    codeList.add("");
                    serialNumLength = 6;
                    appendStr(str,"_",serialNumLength);
                }
            }
        }

        WmsBarcodeRecord wmsBarcodeRecord = barcodeRecordService.selectLastBarcode(str.toString());
        if (wmsBarcodeRecord != null) {
            String pre = CollUtil.join(codeList.subList(0, serialNumIndex), "");
            String lastSerialNum = wmsBarcodeRecord.getBarCode().substring(pre.length(), pre.length()+serialNumLength);
            if (NumberUtil.isLong(lastSerialNum)) {
                codeList.set(serialNumIndex, String.format("%0" + serialNumLength + "d", (Long.parseLong(lastSerialNum) + 1)) );
            } else {
                codeList.set(serialNumIndex, String.format("%0" + serialNumLength + "d", 1));
            }
        } else {
            codeList.set(serialNumIndex, String.format("%0" + serialNumLength + "d", 1));
        }
        String result = CollUtil.join(codeList, StrUtil.isNotEmpty(wmsCodeRule.getBreakCode()) ? wmsCodeRule.getBreakCode() : "");
        if (StrUtil.isNotEmpty(wmsCodeRule.getPrefix())) {
            result = wmsCodeRule.getPrefix() + result;
        }
//        WmsBarcodeRecord barcodeRecord = barcodeRecordService.selectWmsBarcodeRecordByBarcode(result);
//        if (barcodeRecord != null) {
//            throw new ServiceException("条码已存在，请检查条码规则");
//        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println("2023022300001".substring("20230223".length(),"20230223".length()+5));
    }

    private void appendStr(StringBuilder str, String appStr, int qty) {
        for (int i = 0; i < qty; i++) {
            str.append(appStr);
        }
    }
    public WmsCodeRuleProduct selectCommonWmsCodeRuleProduct() {
        return wmsCodeRuleProductMapper.selectCommonWmsCodeRuleProduct();

    }

    public WmsCodeRuleProduct selectWmsCodeRuleProductByProductType(String productType) {
        return wmsCodeRuleProductMapper.selectWmsCodeRuleProductByProductType(productType);
    }
}
